import sys,random
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from NetTools.WordSender import *
from NetTools.WordReceiver import *
from threadTool.thread import *
from NetTools.DeviceListener import *
from NetTools.DeviceHolder import *
from Config import conf


class ChatGUI(QWidget):
    freshListSignal = pyqtSignal()
    newMessageSignal = pyqtSignal(str)
    def __init__(self):
        # 使用父类的构造函数
        super().__init__()
        # 一些信息
        self.addr = "127.0.0.1"
        self.port = 913
        self.currentWord = "123"
        self.userList = []
        self.fitObjList = []
        self.fitObjInfoList = []
        self.currentAddr=None
        self.freshListSignal.connect(self.freshList)
        self.newMessageSignal.connect(self.newMessageShow)
        # 获取电脑分辨率信息
        self.getScreenInfo()
        # 创建设备挂起线程（等待别人发现）
        self.createDeviceHoldThread(conf.ip)
        # 创建文字接收线程
        self.createWordReceiveThread(conf.ip, conf.device_find_port)
        # GUI初始化
        self.initUI()
######################################################################################################
# 界面区

    def getScreenInfo(self):
        # 获取桌面对象
        self.desktop = QApplication.desktop()
        # 获取显示器分辨率大小
        self.screenRect = self.desktop.screenGeometry()
        self.WinHeight = self.screenRect.height()
        self.WinWidth = self.screenRect.width()

    def initUI(self):
        # 根据屏幕分辨率设置窗口大小
        self.setGeometry(0, 0, self.WinWidth, self.WinHeight)
        # 设置窗口标题
        self.setWindowTitle('聊天器')
        # 初始化扫描按钮
        self.initScanButton()
        # 初始化退出按钮
        self.initExitButton()
        # 初始化聊天列表
        self.initChatList()
        # 初始化聊天标题
        self.initChatTitle("test")
        # 初始化聊天框
        self.initChatFrame()
        # 初始化发送框
        self.initInputFrame()
        # 初始化发送按钮
        self.initSendButton()
        # 设置总体透明度
        self.setAllObjOpacity(0.9)
        # 显示GUI
        self.show()

    def initScanButton(self):
        # 创建一个ScanButton
        SizeInfo = [1/50, 8.2/10, 1/5, 1/10]
        self.ScanButton = QPushButton('扫描', self)
        self.ScanButton.setGeometry(
            self.WinWidth*SizeInfo[0], self.WinHeight*SizeInfo[1], self.WinWidth*SizeInfo[2], self.WinHeight*SizeInfo[3])
        self.ScanButton.clicked.connect(lambda: self.createScanDeviceThread(conf.ip, conf.mask))
        self.fitObjList.append(self.ScanButton)
        self.fitObjInfoList.append(SizeInfo)
    
    def initExitButton(self):
        SizeInfo = [1/50+1/5, 8.2/10, 1/5, 1/10]
        self.ExitButton = QPushButton('退出', self)
        self.ExitButton.setGeometry(
            self.WinWidth*SizeInfo[0], self.WinHeight*SizeInfo[1], self.WinWidth*SizeInfo[2], self.WinHeight*SizeInfo[3])
        self.ExitButton.clicked.connect(lambda: self.Exit())
        self.fitObjList.append(self.ExitButton)
        self.fitObjInfoList.append(SizeInfo)

    def initChatList(self):
        SizeInfo = [1/50, 1/50, 2/5, 8/10]
        self.listWidget = QListWidget(parent=self)  # 创建一个listview对象
        self.listWidget.setFont(QFont("华文琥珀",10,QFont.Bold))

        for userinfo in self.userList:
            item = QListWidgetItem()  # 创建QListWidgetItem对象
            widget = self.makeUserListItemWidget(userinfo)
            self.listWidget.addItem(item)  # 添加item
            self.listWidget.setItemWidget(item, widget)  # 为item设置widget

        self.listWidget.setGeometry(
            self.WinWidth*SizeInfo[0], self.WinHeight*SizeInfo[1], self.WinWidth*SizeInfo[2], self.WinHeight*SizeInfo[3])
        self.fitObjList.append(self.listWidget)
        self.fitObjInfoList.append(SizeInfo)
        self.listWidget.clicked.connect(self.chatListOnClick)
    
    def initChatTitle(self,his_username):
        SizeInfo = [2/5+1/20,1/50,1/2,1/30]
        self.chatTitle = QLabel(parent=self)
        self.chatTitle.setText(his_username)
        self.chatTitle.setGeometry(self.WinWidth*SizeInfo[0], self.WinHeight*SizeInfo[1], self.WinWidth*SizeInfo[2], self.WinHeight*SizeInfo[3])
        #标签1的背景填充更改为True，否则无法显示背景
        self.chatTitle.setAutoFillBackground(True)
        palette=QPalette()
        palette.setColor(QPalette.Window,Qt.green)
        # #标签1加载背景
        self.chatTitle.setPalette(palette)
        # #设置文本居中显示
        self.chatTitle.setAlignment(Qt.AlignCenter)
        self.fitObjList.append(self.chatTitle)
        self.fitObjInfoList.append(SizeInfo)

    def initChatFrame(self):
        # 消息显示框
        SizeInfo = [2/5+1/20,4/75,1/2,12/20]
        self.chatFrame = QTextEdit(parent=self)
        self.chatFrame.setGeometry(self.WinWidth*SizeInfo[0], self.WinHeight*SizeInfo[1], self.WinWidth*SizeInfo[2], self.WinHeight*SizeInfo[3])
        self.fitObjList.append(self.chatFrame)
        self.fitObjInfoList.append(SizeInfo)
        self.chatFrame.setFont(QFont('Arial',16))

    def initInputFrame(self):
        # 消息发送框
        SizeInfo = [2/5+1/20,4/75+6/10,1/2,1/6]
        self.inputFrame = QTextEdit(parent=self)
        self.inputFrame.setGeometry(self.WinWidth*SizeInfo[0], self.WinHeight*SizeInfo[1], self.WinWidth*SizeInfo[2], self.WinHeight*SizeInfo[3])
        self.fitObjList.append(self.inputFrame)
        self.fitObjInfoList.append(SizeInfo)
    
    def initSendButton(self):
        SizeInfo = [2/5+1/20, 4/75+6/10+1/6, 1/5, 1/10]
        self.SendButton = QPushButton('发送', self)
        self.SendButton.setGeometry(
            self.WinWidth*SizeInfo[0], self.WinHeight*SizeInfo[1], self.WinWidth*SizeInfo[2], self.WinHeight*SizeInfo[3])
        self.SendButton.clicked.connect(lambda: self.sendWord(self.currentAddr[0],self.currentAddr[1],self.inputFrame.toPlainText()))
        self.fitObjList.append(self.SendButton)
        self.fitObjInfoList.append(SizeInfo)

    
    def makeUserListItemWidget(self,userinfo):
        # 读取属性
        this_username = userinfo['username']
        avatar_id = userinfo['avatarid']
        this_addr = userinfo['addr']
        # unreadCount = userinfo['unreadCount']
        # latestMessage = userinfo['latestMessage']
        unreadCount=0
        latestMessage="xxxxxxxxx"
        # 总Widget
        thisWidget = QWidget()

        # 总体横向布局
        layout_main = QHBoxLayout()
        map_l = QLabel()  # 头像显示
        map_l.setFixedSize(80, 80) #头像大小
        maps = QPixmap("./images/avatars/%s.png"%userinfo['avatarid']).scaled(80,80)
        map_l.setPixmap(maps)
        

        # 右边的纵向布局
        layout_right = QVBoxLayout()

        # 右下的的横向布局
        layout_right_down = QHBoxLayout()  # 右下的横向布局
        unreadCountLabel = QLabel()
        latestMessageLabel = QLabel()
        this_addrLabel = QLabel()
        unreadCountLabel.setText(str(unreadCount))
        latestMessageLabel.setText(str(latestMessage))
        this_addrLabel.setText(str(this_addr))

        layout_right_down.addWidget(unreadCountLabel)
        layout_right_down.addWidget(latestMessageLabel)
        layout_right_down.addWidget(this_addrLabel)

        # 按照从左到右, 从上到下布局添加
        layout_main.addWidget(map_l)  # 最左边的头像
        this_usernameLabel = QLabel()
        this_usernameLabel.setText(this_username)
        layout_right.addWidget(this_usernameLabel)  # 右边的纵向布局
        layout_right.addLayout(layout_right_down)  # 右下角横向布局

        layout_main.addLayout(layout_right)  # 右边的布局

        thisWidget.setLayout(layout_main)  # 布局给wight
        return thisWidget
    
    def setAllObjOpacity(self,opacity):
        for obj in self.fitObjList:
            self.setOpacity(opacity,obj)

##############################################################################################
# 线程区

    def createDeviceHoldThread(self, ip):
        self.DeviceHoldThread = thread(lambda: self.initDeviceHolder(ip))
        self.DeviceHoldThread.start()
    
    def createScanDeviceThread(self,ip,mask):
        self.DeviceScanThread = thread(lambda: self.scan(ip,mask))
        self.DeviceScanThread.start()

    def createWordReceiveThread(self, ip, port):
        self.WordReceiverThread = thread(
            lambda: self.initWordReceiver(ip, port))
        self.WordReceiverThread.start()

########################################################################################################
# 功能区

    def freshList(self):
        #实时刷新界面
        self.listWidget.clear()
        for userinfo in self.userList:
            item = QListWidgetItem()  # 创建QListWidgetItem对象
            item.setSizeHint(QSize(self.WinWidth/5,self.WinHeight/12))
            r,g,b = tuple(random.choice(range(32,256,32)) for _ in range(3))
            item.setBackground(QColor(r,g,b))
            widget = self.makeUserListItemWidget(userinfo)
            self.listWidget.addItem(item)  # 添加item
            self.listWidget.setItemWidget(item, widget)  # 为item设置widget

    def scan(self, ip, mask):
        print("scan device in Net......")
        self.ScanButton.setText("扫描中......")
        myDeviceListener = DeviceListener(ip, mask)
        DeviceList = myDeviceListener.scan()
        print(DeviceList)
        self.ScanButton.setText("扫描")
        infoList=[]
        for item in DeviceList:
            username = item[0]
            addr = item[1]
            avatar = item[2]
            infoList.append({'username':username,'addr':addr,'avatarid':avatar})
        self.userList = infoList
        self.freshListSignal.emit()

    def initDeviceHolder(self, ip):
        print("初始化设别挂起器")
        self.myDeviceHolder = DeviceHolder(ip)
        self.myDeviceHolder.hold()

    def initWordReceiver(self, ip, port):
        print("初始化文字接收器")
        self.myWordReceiver = WordReceiver(self,ip, port)
        # self.myWordReceiver.receiveWord()

    def sendWord(self, addr, port, word):
        print("send %s to %s,%s" % (word,addr, port))
        self.myWordSender.sendWord(word)
        self.chatFrame.setAlignment(Qt.AlignRight)
        self.chatFrame.setTextColor(QColor(0,0,255))
        self.chatFrame.insertPlainText("%s: %s\n"%(conf.username,word))

        
    
    def fitBackground(self):
        palette = QPalette()
        pix = QPixmap("./images/1.jpg")
        pix = pix.scaled(self.width(),self.height())
        palette.setBrush(QPalette.Background,QBrush(pix))
        self.setPalette(palette)
    
    def setOpacity(self,opacity,Obj):
        pl = Obj.palette()
        pl.setBrush(QPalette.Base,QBrush(QColor(255,255,255,255*opacity)))
        Obj.setPalette(pl)

    def newMessageShow(self,msg):
        self.chatFrame.setAlignment(Qt.AlignLeft)
        self.chatFrame.setTextColor(QColor(255,0,0))
        self.chatFrame.insertPlainText("%s: %s\n"%(self.his_username,msg))

    
    def Exit(self):
        self.close()

##################################################################################################
# 事件处理区
    def chatListOnClick(self, event):
        # print(self.userList.keys())
        print("你选择了：",self.userList[event.row()]['username'])
        addr = self.userList[event.row()]['addr']
        print(addr)
        self.chatTitle.setText(self.userList[event.row()]['username']+"  "+str(addr))
        self.currentAddr=addr
        self.his_username = self.userList[event.row()]['username']
        print("初始化文字发送器")
        try:
            self.myWordSender.close()
        except Exception:
            pass
        self.myWordSender = WordSender(addr[0], addr[1])


    def resizeEvent(self, event):
        w = event.size().width()
        h = event.size().height()
        self.fitAllObj(w, h)
        self.fitBackground()

    def fitAllObj(self, w, h):
        for Obj, info in zip(self.fitObjList, self.fitObjInfoList):
            Obj.setGeometry(w*info[0], h*info[1], w*info[2], h*info[3])


if __name__ == '__main__':

    app = QApplication(sys.argv)
    ex = ChatGUI()
    sys.exit(app.exec_())
